package top.zhaojx.rpc.transport.handler;

import lombok.extern.slf4j.Slf4j;
import top.zhaojx.rpc.entity.RpcRequest;
import top.zhaojx.rpc.entity.RpcResponse;
import top.zhaojx.rpc.enumration.ResponseCode;
import top.zhaojx.rpc.factory.SingletonFactory;
import top.zhaojx.rpc.provider.NewServiceProvider;
import top.zhaojx.rpc.provider.ServiceProvider;
import top.zhaojx.rpc.provider.ServiceProviderImpl;
import top.zhaojx.rpc.provider.ZkServiceProviderImpl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 进行过程调用的处理器
 */
@Slf4j
public class RpcRequestHandler {

    private final NewServiceProvider serviceProvider;

    public RpcRequestHandler() {
        serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
    }

    public Object handle(RpcRequest rpcRequest) {
        Object result = null;
        Object service = serviceProvider.getService(rpcRequest.getRpcServiceName());
        try {
            result = invokeTargetMethod(rpcRequest, service);
            log.info("服务:{} 成功调用方法:{}", rpcRequest.getInterfaceName(), rpcRequest.getMethodName());
        } catch (IllegalAccessException | InvocationTargetException e) {
            log.error("调用或发送时有错误发生：", e);
        } return result;
    }

    private Object invokeTargetMethod(RpcRequest rpcRequest, Object service) throws IllegalAccessException, InvocationTargetException {
        Method method;
        try {
            method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
        } catch (NoSuchMethodException e) {
            return RpcResponse.fail(ResponseCode.METHOD_NOT_FOUND);
        }
        return method.invoke(service, rpcRequest.getParameters());
    }
}
